package middlewares

import (
	"bytes"
	"gitee.com/yijimu/gin-frame/utils"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

// GinLogger 接收gin框架默认的日志
func GinLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()
		url := c.Request.URL

		path := url.Path // 请求路径
		// 防止黑客使得 path 过长
		if len(path) > 1024 {
			path = path[:1024] + "..."
		}

		reqBody, _ := utils.GinGetRequestBody(c)
		if len(reqBody) > 2048 {
			reqBody = string(reqBody[:2048]) + "..."
		}

		// 获取请求响应数据 装饰器模式
		writer := &utils.GinCustomResponseWriter{
			ResponseWriter: c.Writer,
			Body:           bytes.NewBufferString(""),
		}
		c.Writer = writer

		c.Next()

		if !strings.HasPrefix(path, "/swagger/") && !strings.HasPrefix(path, "/asynq_ui/") && c.Request.Method != "OPTIONS" {
			zap.L().WithOptions(
				zap.AddCaller(),
			).Info("Debug",
				zap.String("log_type", "request"),
				zap.Int("status", c.Writer.Status()),
				zap.Any("request", map[string]string{
					"url":        c.Request.Method + " " + url.String(),
					"req":        reqBody,
					"resp":       writer.Body.String(),
					"ip":         c.ClientIP(),
					"user-agent": c.Request.UserAgent(),
				}),
				zap.String("errors", c.Errors.ByType(gin.ErrorTypePrivate).String()),
				zap.Duration("cost", time.Since(start)),
			)
		}
	}
}
